package com.leo.util;

import java.util.List;
import java.util.ArrayList;

import java.util.regex.Pattern;

/**
 * Describe class Schema here.
 *
 *
 * Created: Mon Apr 15 23:14:12 2013
 *
 * @author <a href="mailto:leo@leo-pc">Leo</a>
 * @version 1.0
 */
public class Schema {
    private List<String> unitList;
    private List<Integer> rangeList;
    private List<String> nameList;
    // TODO : should has a type list.
    /**
     * Get the <code>RangeList</code> value.
     *
     * @return a <code>List<Integer></code> value
     */
    public final List<Integer> getRangeList() {
	return rangeList;
    }

    /**
     * Get the <code>UnitList</code> value.
     *
     * @return a <code>List<String></code> value
     */
    public final List<String> getUnitList() {
	return unitList;
    }

    /**
     * Get the <code>NameList</code> value.
     *
     * @return a <code>List<String></code> value
     */
    public final List<String> getNameList() {
	return nameList;
    }
    
    /**
     * Creates a new <code>Schema</code> instance.
     *
     */
    public Schema() {
    }

    
    public boolean add(String name, Integer range, String unit) {
	if (nameList == null )
	    nameList = new ArrayList<String>();
	if (rangeList == null )
	    rangeList = new ArrayList<Integer>();
	if (unitList == null )
	    unitList = new ArrayList<String>();

	if ( nameList.indexOf(name) != -1 || name == null ||
	     name.length() == 0 || name.contains(",") || name.contains(":"))
	    return false;
	nameList.add(name);
	rangeList.add(range);
	unitList.add(unit);
	return true;
    }

    public boolean remove(String name) {
	int index = nameList.indexOf(name);
	if (index == -1 )
	    return false;
	nameList.remove(index);
	unitList.remove(index);
	rangeList.remove(index);
	return true;
    }

    public boolean remove(int index) {
	return this.remove(nameList.get(index));
    }

    public boolean test(int index) {
	return index < nameList.size();
    }

    public boolean test(String record) {
	int sum = 0;
	for (int value : rangeList)
	    sum += value;
	return record != null && record.length() == sum;
    }

    public Schema subSchema(List<Integer> columnList) {
	Schema newSchema = new Schema();
	for (int i : columnList) {
	    if (!test(i))
		throw new RuntimeException();

	    newSchema.add(nameList.get(i), rangeList.get(i), unitList.get(i));
	}
	return newSchema;
    }

    public boolean load(String config) {
	if (config == null)
	    return false;
	String regex = "[^,:]+(,[^,:]+)*:\\d+(,\\d+)*:[^,:]+(,[^,:]+)*";
	if (!Pattern.matches(regex, config))
	    return false;

	String[] list = config.split(":");
	nameList = new ArrayList<String>();
	for (String aa : list[0].split(",") )
	    nameList.add(aa);
	
	rangeList = new ArrayList<Integer>();
	for (String aa : list[1].split(",") )
	    rangeList.add(Integer.parseInt(aa));

	unitList = new ArrayList<String>();
	for (String aa : list[2].split(",") )
	    unitList.add(aa);
	return true;
    }

    public String genConfig() {
	String config = "";
	for (String name : nameList) {
	    if (nameList.indexOf(name) != 0)
		config = config + "," ;
	    config += name;
	}

	config += ":";

	for (int range : rangeList) {
	    if (rangeList.indexOf(range) != 0)
		config = config + "," ;
	    config += range;
	}

	config += ":";

	for (String unit : unitList) {
	    if (unitList.indexOf(unit) != 0)
		config = config + "," ;
	    config += unit;
	}
	
	return config;
    }

    public int getInt(String record, int index) {
	String value = getString(record, index);
	return Integer.parseInt(value); 
    }

    public String getString(String record, int index) {
	if (index < 0 || index >= nameList.size() || !test(record))
	    throw new RuntimeException("index below 0 or out of bound.Or record do not follow the format.");
	int start = 0;
	for (int i = 0; i < index; i ++)
	    start += rangeList.get(i);

	return record.substring(start, start + rangeList.get(index));
    }

}
